package org.io4j.resource;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;

import org.io4j.util.Argument;

/**
 * A {@code Resource} that reads its contents from a byte array.
 */
public class ByteArrayResource extends BaseResource {

	private final byte[] byteArray;
	private final String name;
	private final long modificationTimestamp;

	/**
	 * Constructs a {@code ByteArrayResource} from a byte array (with the default
	 * name).
	 * 
	 * @throws IllegalArgumentException
	 *            if byte array is {@code null}
	 */
	public ByteArrayResource(byte[] byteArray) {
		this(byteArray, "resource created from a byte array");
	}

	/**
	 * Constructs a {@code ByteArrayResource} from a byte array and a specified
	 * name.
	 * 
	 * @throws IllegalArgumentException
	 *            if byte array is {@code null}, or name is {@code null} or empty
	 */
	public ByteArrayResource(byte[] byteArray, String name) {
		Argument.isNotNull(byteArray, "Byte array is null");
		Argument.isNotEmpty(name, "Name is null or empty");
		this.byteArray = Arrays.copyOf(byteArray, byteArray.length);
		this.name = name;
		this.modificationTimestamp = System.currentTimeMillis();
	}

	@Override
	public byte[] readBytes() {
		return Arrays.copyOf(byteArray, byteArray.length);
	}

	public InputStream openInputStream() {
		return new ByteArrayInputStream(byteArray);
	}

	public URL getUrl() {
		throw new ResourceResolutionException("Cannot resolve URL for " + name);
	}

	public String getName() {
		return name;
	}

	@Override
	public long getContentLength() {
		return byteArray.length;
	}

	/**
	 * {@inheritDoc} Creation time is returned for {@code ByteArrayResource}.
	 */
	@Override
	public long getModificationTimestamp() {
		return modificationTimestamp;
	}
}
